package com.ben.multiple.util;

import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * http 请求；适合高并发
 *
 * @author ben
 * @date 2019/7/18
 */
public interface HttpClientUtils {
    /**
     * Get 请求
     *
     * @param url     请求路径
     * @param params  请求参数
     * @param headers 请求头
     * @param charset 字符编码
     * @return String
     * @throws Exception Exception
     */
    static String doGet(String url, Map<String, String> params, Map<String, String> headers, Charset charset) throws Exception {
        // 1. 创建 uri
        if (url == null || "".equals(url)) {
            throw new RuntimeException("url is null");
        }
        URI uri = new URIBuilder(url).build();
        // 2. 创建请求
        RequestBuilder requestBuilder = RequestBuilder.get(uri);
        // 设置连接超时时间     10s
        requestBuilder.setConfig(RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).setConnectionRequestTimeout(10000).build());
        // 2.1 请求参数
        if (params != null) {
            params.forEach(requestBuilder::addParameter);
        }
        // 2.2 请求头
        if (headers != null) {
            headers.forEach(requestBuilder::addHeader);
        }
        // 2.3 请求字符编码
        if (charset == null) {
            charset = StandardCharsets.UTF_8;
        }
        HttpUriRequest request = requestBuilder.setCharset(charset).build();
        // 3. 执行请求
        CloseableHttpResponse httpResponse = HttpClientBuilder.create().setMaxConnPerRoute(10000).setMaxConnTotal(100000).build().execute(request);
        if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            return null;
        }
        try {
            return EntityUtils.toString(httpResponse.getEntity(), charset);
        } finally {
            org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpResponse);
        }
    }

    static String doGet(String url) throws Exception {
        return doGet(url, null, null, null);
    }

    static String doParamGet(String url, Map<String, String> params) throws Exception {
        return doGet(url, params, null, null);
    }

    static String doHeaderGet(String url, Map<String, String> headers) throws Exception {
        return doGet(url, null, headers, null);
    }

    static String doGet(String url, Charset charset) throws Exception {
        return doGet(url, null, null, charset);
    }

    static String doGet(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        return doGet(url, params, headers, null);
    }

    static String doParamGet(String url, Map<String, String> params, Charset charset) throws Exception {
        return doGet(url, params, null, charset);
    }

    static String doHeaderGet(String url, Map<String, String> headers, Charset charset) throws Exception {
        return doGet(url, null, headers, charset);
    }

    static InputStream doGetStream(String url) throws Exception {
        // 1. 创建 uri
        if (url == null || "".equals(url)) {
            throw new RuntimeException("url is null");
        }
        URI uri = new URIBuilder(url).build();
        // 2. 创建请求
        RequestBuilder requestBuilder = RequestBuilder.get(uri);
        // 设置连接超时时间     10s
        requestBuilder.setConfig(RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).setConnectionRequestTimeout(10000).build());
        HttpUriRequest request = requestBuilder.setCharset(StandardCharsets.UTF_8).build();
        // 3. 执行请求
        CloseableHttpResponse httpResponse = HttpClientBuilder.create().setMaxConnPerRoute(10000).setMaxConnTotal(100000).build().execute(request);
        if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            return null;
        }
        try {
            return httpResponse.getEntity().getContent();
        } finally {
            org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpResponse);
        }
    }


    /**
     * Post 请求
     *
     * @param url     请求路径
     * @param headers 请求头
     * @param charset 字符编码
     * @param content 请求实体  json
     * @return String
     * @throws Exception Exception
     */
    static String doPost(String url, Map<String, String> headers, Charset charset, String content) throws Exception {
        // 1. 创建 uri
        if (null == url || "".equals(url)) {
            throw new RuntimeException("url is null");
        }
        URI uri = new URIBuilder(url).build();
        // 2. 创建请求
        RequestBuilder requestBuilder = RequestBuilder.post(uri);
        // 2.1 设置连接超时时间     10s
        requestBuilder.setConfig(RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).setConnectionRequestTimeout(10000).build());
        // 2.2 请求头
        if (headers != null) {
            headers.forEach(requestBuilder::addHeader);
        }
        // 2.3 请求字符编码
        if (charset == null) {
            charset = StandardCharsets.UTF_8;
        }
        // 2.4 请求实体
        if (content != null) {
            EntityBuilder entityBuilder = EntityBuilder.create().setText(content).setContentType(ContentType.APPLICATION_JSON).setContentEncoding(StandardCharsets.UTF_8.name());
            requestBuilder.setEntity(entityBuilder.build());
        }
        HttpUriRequest request = requestBuilder.setCharset(charset).build();
        // 3. 执行请求
        CloseableHttpResponse httpResponse = HttpClientBuilder.create().setMaxConnPerRoute(10000).setMaxConnTotal(100000).build().execute(request);
        if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            return null;
        }
        try {
            return EntityUtils.toString(httpResponse.getEntity(), charset);
        } finally {
            org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpResponse);
        }
    }

    static String doPost(String url) throws Exception {
        return doPost(url, null, null, null);
    }

    static String doPost(String url, Map<String, String> headers) throws Exception {
        return doPost(url, headers, null, null);
    }

    static String doPost(String url, Charset charset) throws Exception {
        return doPost(url, null, charset, null);
    }

    static String doPost(String url, String content) throws Exception {
        return doPost(url, null, null, content);
    }

    static String doPost(String url, Map<String, String> headers, Charset charset) throws Exception {
        return doPost(url, headers, charset, null);
    }

    static String doPost(String url, Map<String, String> headers, String content) throws Exception {
        return doPost(url, headers, null, content);
    }

    static String doPost(String url, Charset charset, String content) throws Exception {
        return doPost(url, null, charset, content);
    }
}
